#include <iostream>
#include <string>
#include <unistd.h>
#include <time.h>
#include<sys/select.h>
#include <sys/types.h>
#include "Socket.h"
#include "Log.hpp"
using namespace std;

#define BITS 8
#define NUM (sizeof(fd_set)*BITS)
#define FD_NONE -1


class Select
{
public:
    Select(const uint16_t &port = 8080) 
    :_port(port)
    {
        _listensock=Sock().Socket();
        Sock().Bind(_listensock,_port);
        Sock().Listen(_listensock);

        logMessage(DEBUG,"%s","create base socket success");
        //创建
        for(int i = 0; i < NUM; i++) 
            _fd_array[i] = FD_NONE;
        // 规定 : _fd_array[0] = _listensock;
        _fd_array[0] = _listensock;
    }
    void Start()
    {
        while(true)
        {
            fd_set rfds;//创建文件集合
            FD_ZERO(&rfds);//清空
            //FD_SET(_listensock,&rfds);//设置
            struct timeval waittime = {1, 0};//等待时间
            int maxfd = _listensock;
            for(int i=0;i<NUM;i++)
            {
                if(_fd_array[i]==FD_NONE) continue;
                FD_SET(_fd_array[i], &rfds);//将listen设置到集合中
                maxfd=_fd_array[i]>maxfd?_fd_array[i]:maxfd;
            }
            int n=select(maxfd+1,&rfds,nullptr,nullptr,&waittime);
            if(n==0)//超时
            {
                logMessage(DEBUG,"wait proces");
            }
            else if(n<0)//失败
            {
                logMessage(WARING,"error");
                return ;
            }
            else//成功
            {
                logMessage(DEBUG,"right");
                //处理数据
                HandlerEvent(rfds);
            }
        }
    }

private:
void HandlerEvent(const fd_set& rfds)
{
    for(int i=0;i<NUM;i++)
    {
        if(_fd_array[i]==FD_NONE) continue;
        if (FD_ISSET(_fd_array[i], &rfds))
        {
            // 指定的fd，读事件就绪
            //  读事件就绪：连接时间到来，accept
            if (_fd_array[i] == _listensock)
                Accepter();
            else
                Recver(i);
        }
    }
}
void Accepter()
{
    string clientip;
    uint16_t clientport = 0;

    int sock=Sock().Accept(_listensock,&clientport,&clientip);
    if(sock<0)
    {
        logMessage(WARING,"create error %d,%s",errno,strerror(errno));
        return;
    }
    int pos=1;
    for(pos;pos<NUM;pos++)
    {
        if(_fd_array[pos]==FD_NONE) break;
    }
    if(pos==NUM) 
    {
        logMessage(WARING, "%s:%d", "select server already full，close: %d", sock);
        close(sock);
    }
    else 
        _fd_array[pos]=sock;
}
void Recver(int pos)
{
    // 读事件就绪：INPUT事件到来、recv，read
    char buf[1024];
    ssize_t n=read(_fd_array[pos],buf,sizeof buf);
    if(n<0)
    {
        logMessage(ERROR,"read fail :%d %s",errno,strerror(errno));
    }
    else 
    {
        logMessage(DEBUG, "%d sock recv error, %d : %s", _fd_array[pos], errno, strerror(errno));
        close(_fd_array[pos]);
        _fd_array[pos]=NUM;
    }
}
private:
    uint16_t _port;//端口号
    int _listensock;//套接字
    int _fd_array[NUM];
    // int _fd_write[NUM];
    // std::vector<int> arr;
};